#ifndef DAC8760_H_
#define DAC8760_H_

#include "main.h"

#include "std.h"

// DAC8760 Address Functions
#define DAC8760_WRITE_NOP_REGISTER			         0x00
#define DAC8760_WRITE_DATA_REGISTER			         0x01
#define DAC8760_READ_REGISTER    			         0x02
#define DAC8760_WRITE_CONTROL_REGISTER			     0x55
#define DAC8760_WRITE_RESET_REGISTER		     	 0x56
#define DAC8760_WRITE_CONFIGURATION_REGISTER		 0x57
#define DAC8760_WRITE_GAIN_CALIBRATION_REGISTER		 0x58
#define DAC8760_WRITE_ZERO_CALIBRATION_REGISTER		 0x59
#define DAC8760_WRITE_WATCHDOG_TIMER_RESET		     0x95

// DAC8760 Register Read Address Functions
#define DAC8760_READ_STATUS_REGISTER                 0x00
#define DAC8760_READ_DATA_REGISTER                   0x01
#define DAC8760_READ_CONTROL_REGISTER                0x02
#define DAC8760_READ_CONFIGURATION_REGISTER          0x0B
#define DAC8760_READ_GAIN_CALIBRATION_REGISTER       0x13
#define DAC8760_READ_ZERO_CALIBRATION_REGISTER       0x17

// Control Register Settings
#define DAC8760_CLRSEL_SHIFT                         15
#define DAC8760_CLRSEL                               (1 << DAC8760_CLRSEL_SHIFT)
#define DAC8760_OVR_SHIFT                            14
#define DAC8760_OVR                                  (1 << DAC8760_OVR_SHIFT)
#define DAC8760_REXT_SHIFT                           13
#define DAC8760_REXT                                 (1 << DAC8760_REXT_SHIFT)
#define DAC8760_OUTEN_SHIFT                          12
#define DAC8760_OUTEN                                (1 << DAC8760_OUTEN_SHIFT)
#define DAC8760_SRCLK_SHIFT                          8
#define DAC8760_UPDATE_FREQUENCY_258065              (0 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_200000              (1 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_153845              (2 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_131145              (3 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_115940              (4 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_69565               (5 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_37560               (6 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_25805               (7 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_20150               (8 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_16030               (9 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_10295               (10 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_8280                (11 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_6900                (12 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_5530                (13 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_4240                (14 << DAC8760_SRCLK_SHIFT)
#define DAC8760_UPDATE_FREQUENCY_3300                (15 << DAC8760_SRCLK_SHIFT)
#define DAC8760_SRSTEP_SHIFT                         5
#define DAC8760_SLEW_RATE_STEP_SIZE_1                (0 << DAC8760_SRSTEP_SHIFT)
#define DAC8760_SLEW_RATE_STEP_SIZE_2                (1 << DAC8760_SRSTEP_SHIFT)
#define DAC8760_SLEW_RATE_STEP_SIZE_4                (2 << DAC8760_SRSTEP_SHIFT)
#define DAC8760_SLEW_RATE_STEP_SIZE_8                (3 << DAC8760_SRSTEP_SHIFT)
#define DAC8760_SLEW_RATE_STEP_SIZE_16               (4 << DAC8760_SRSTEP_SHIFT)
#define DAC8760_SLEW_RATE_STEP_SIZE_32               (5 << DAC8760_SRSTEP_SHIFT)
#define DAC8760_SLEW_RATE_STEP_SIZE_64               (6 << DAC8760_SRSTEP_SHIFT)
#define DAC8760_SLEW_RATE_STEP_SIZE_128              (7 << DAC8760_SRSTEP_SHIFT)
#define DAC8760_SREN_SHIFT                           4
#define DAC8760_SLEW_RATE_ENABLE                     (1 << DAC8760_SREN_SHIFT)
#define DAC8760_DCEN_SHIFT                           3
#define DAC8760_DAISY_CHAIN_ENABLE                   (1 << DAC8760_DCEN_SHIFT)
#define DAC8760_RANGE_SHIFT                          0
#define DAC8760_RANGE_0V_5V                          (0 << DAC8760_RANGE_SHIFT)
#define DAC8760_RANGE_0V_10V                         (1 << DAC8760_RANGE_SHIFT)
#define DAC8760_RANGE_M5V_P5V                        (2 << DAC8760_RANGE_SHIFT)
#define DAC8760_RANGE_M10V_P10V                      (3 << DAC8760_RANGE_SHIFT)
#define DAC8760_RANGE_NOT_ALLOWED                    (4 << DAC8760_RANGE_SHIFT)
#define DAC8760_RANGE_4MA_20MA                       (5 << DAC8760_RANGE_SHIFT)
#define DAC8760_RANGE_0MA_20MA                       (6 << DAC8760_RANGE_SHIFT)
#define DAC8760_RANGE_0MA_24MA                       (7 << DAC8760_RANGE_SHIFT)

// Configuration Register Settings
#define DAC8760_IOUT_RANGE_SHIFT                     9
#define DAC8760_IOUT_RANGE_DISABLED                  (0 << DAC8760_IOUT_RANGE_SHIFT)
#define DAC8760_IOUT_RANGE_4MA_20MA                  (1 << DAC8760_IOUT_RANGE_SHIFT)
#define DAC8760_IOUT_RANGE_0MA_20MA                  (2 << DAC8760_IOUT_RANGE_SHIFT)
#define DAC8760_IOUT_RANGE_0MA_24MA                  (3 << DAC8760_IOUT_RANGE_SHIFT)
#define DAC8760_DUAL_OUTEN_SHIFT                     8
#define DAC8760_DUAL_OUT_ENABLE                      (1 << DAC8760_DUAL_OUTEN_SHIFT)
#define DAC8760_APD_SHIFT                            7
#define DAC8760_APD                                  (1 << DAC8760_APD_SHIFT)
#define DAC8760_CALEN_SHIFT                          5
#define DAC8760_CAL_ENABLE                           (1 << DAC8760_CALEN_SHIFT)
#define DAC8760_HARTEN_SHIFT                         4
#define DAC8760_HART_ENABLE                          (1 << DAC8760_HARTEN_SHIFT)
#define DAC8760_CRCEN_SHIFT                          3
#define DAC8760_CRC_ENABLE                           (1 << DAC8760_CRCEN_SHIFT)
#define DAC8760_WDEN_SHIFT                           2
#define DAC8760_WD_ENABLE                            (1 << DAC8760_WDEN_SHIFT)
#define DAC8760_WDPD_SHIFT                           0
#define DAC8760_WD_TIMEOUT_10MS                     (0 << DAC8760_WDPD_SHIFT)
#define DAC8760_WD_TIMEOUT_51MS                     (1 << DAC8760_WDPD_SHIFT)
#define DAC8760_WD_TIMEOUT_102MS                    (2 << DAC8760_WDPD_SHIFT)
#define DAC8760_WD_TIMEOUT_204MS                    (3 << DAC8760_WDPD_SHIFT)

// Reset Register Settings
#define DAC8760_RESET_SHIFT                         0
#define DAC8760_RESET                               (1 << DAC8760_RESET_SHIFT)

// STATUS Register Settings
#define DAC8760_CRC_FLT_SHIFT                       4
#define DAC8760_CRC_ERROR                           (1 << DAC8760_CRC_FLT_SHIFT)
#define DAC8760_WDT_FLT_SHIFT                       3
#define DAC8760_WDT_TIMEOUT                         (1 << DAC8760_WDT_FLT_SHIFT)
#define DAC8760_I_FLT_SHIFT                         2
#define DAC8760_IOUT_ERROR                          (1 << DAC8760_I_FLT_SHIFT)
#define DAC8760_SR_ON_SHIFT                         1
#define DAC8760_SR_ON                               (1 << DAC8760_SR_ON_SHIFT)
#define DAC8760_T_FLT_SHIFT                         0
#define DAC8760_TEMP_ERROR                          (1 << DAC8760_T_FLT_SHIFT)



typedef struct
{
    uint8_t chan;

    SPI_HandleTypeDef *spix;

    GPIO_TypeDef *gpio_cs;
    uint16_t gpio_pin_cs;
    GPIO_PinState cs_valid;

    
    GPIO_TypeDef *gpio_alarm;
    uint16_t gpio_pin_alarm;
    GPIO_PinState alarm_valid;

    uint8_t in_data[3];

} t_dac8760,*p_dac8760;


extern t_dac8760 dac8760[2];

void dac8760_init(p_dac8760 dev, uint8_t chan, SPI_HandleTypeDef *spix, GPIO_TypeDef *gpio_cs, uint16_t gpio_pin_cs, GPIO_PinState cs_valid, GPIO_TypeDef *gpio_alarm, uint16_t gpio_pin_alarm, GPIO_PinState alarm_valid);
void dac8760_write_reg(p_dac8760 dev, uint8_t addr,uint16_t data);
void dac8760_read_reg(p_dac8760 dev,uint8_t addr,uint8_t *data);
void dac8760_setup(p_dac8760 dev,uint16_t controlReg, uint16_t configurationReg, uint16_t gainCalReg, uint16_t zeroCalReg);
void dac8760_reset(p_dac8760 dev);
void dac8760_nop(p_dac8760 dev);
void dac8760_set_out_value(p_dac8760 dev,uint16_t value);
uint8_t dac8760_read_status(p_dac8760 dev);

void test_dac8760(p_dac8760 dev);

#endif /* DAC8760_H_ */
